﻿using System;
using System.Security.Principal;
using System.Web;
using System.Net;
using System.IO;
using System.Web.SessionState;
using SoftwareMonkeys.Scriptech.Diagnostics;

namespace SoftwareMonkeys.Scriptech.Scripts
{
	public class AsyncScriptHttpHandler : IHttpAsyncHandler, IRequiresSessionState
	{
		public bool IsReusable { get { return false; } }

		public string VirtualPath = String.Empty;
		
		private HttpContext _context;
		private HttpWebRequest scriptRequest;
		
		public AsyncScriptHttpHandler(string virtualPath)
		{
			VirtualPath = virtualPath;
		}
		
		public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
		{
			IAsyncResult result = null;
			using (LogGroup logGroup = LogGroup.StartDebug("Beginning async process request."))
			{
				_context = context;
								
				LogWriter.Debug("Virtual path: " + VirtualPath);
				
				string url = new UrlMapper().MapUrl(VirtualPath);
				
				LogWriter.Debug("Script URL: " + url);
				
				scriptRequest = (HttpWebRequest)HttpWebRequest.Create(url);
				
				AddCookieHeaders(scriptRequest);
				
				result = scriptRequest.BeginGetResponse(cb, extraData);
			}
			return result;
		}

		public void EndProcessRequest(IAsyncResult result)
		{
			//using (LogGroup logGroup = LogGroup.StartDebug("Ending async process request."))
			//{
			
			try
			{
				using (HttpWebResponse response = (HttpWebResponse)scriptRequest.EndGetResponse(result))
				{
					StreamReader reader = new StreamReader(response.GetResponseStream());
					while (reader.Peek() != -1)
					{
						string text = reader.ReadLine();
						_context.Response.Write(text);
						_context.Response.Write(Environment.NewLine); // new line is important
						
					}
				}
			}
			catch (WebException ex)
			{
				LogWriter.Error(ex);
			}
			
			//	LogWriter.Debug("# chars: " + text.Length.ToString());
			
			//}
		}

		public void ProcessRequest(HttpContext context)
		{
			throw new InvalidOperationException();
		}
		
		/// <summary>
		/// Adds the current cookies to the header of the requests.
		/// </summary>
		/// <param name="request"></param>
		public void AddCookieHeaders(WebRequest request)
		{
			string headerString = String.Empty;
			foreach (string key in _context.Request.Cookies.Keys)
			{
				HttpCookie cookie = _context.Request.Cookies[key];
				
				headerString = headerString + key + "=" + cookie.Value + "; ";
			}
			
			request.Headers.Add(HttpRequestHeader.Cookie, headerString);
		}
	}
}
